Native Query হল একটি SQL কুয়েরি যা JPA (Java Persistence API) বা Hibernate এর মাধ্যমে ব্যবহার করা হয়, তবে এটি JPA বা Hibernate এর নিজস্ব কুয়েরি ল্যাঙ্গুয়েজ (JPQL - Java Persistence Query Language) এর পরিবর্তে আসল SQL ব্যবহার করে। Native Query ব্যবহার করে ডেভেলপাররা সরাসরি ডেটাবেসের SQL কুয়েরি লেখার মাধ্যমে জটিল কুয়েরি বা ডেটাবেস স্পেসিফিক অপারেশন সম্পাদন করতে পারেন।
Native Query এর প্রয়োজনীয়তা
Native Query ব্যবহারের প্রয়োজনীয়তা তখনই দেখা দেয় যখন JPQL অথবা HQL (Hibernate Query Language) দ্বারা কিছু জটিল ডেটাবেস অপারেশন সম্পাদন করা সম্ভব না হয় বা ডেটাবেস নির্দিষ্ট কিছু বৈশিষ্ট্য ব্যবহার করতে হয়। JPQL এবং HQL জেনেরিক কুয়েরি ভাষা, যা মূলত Java Objects এবং Entity Classes এর সাথে কাজ করে, কিন্তু এই কুয়েরি ল্যাঙ্গুয়েজের সীমাবদ্ধতা রয়েছে, বিশেষ করে যখন ডেটাবেসের বিশেষ কিছু ফিচার বা ফাংশনালিটি ব্যবহার করতে হয়।
Native Query ব্যবহারের মাধ্যমে আপনি ডেটাবেস স্পেসিফিক কুয়েরি অপ্টিমাইজেশন, ফাংশন, প্রোসিডিউর কল, বা এমন কোনো ফিচার ব্যবহার করতে পারেন যা JPQL সমর্থন করে না।
Native Query এর সুবিধা
- ডেটাবেস নির্দিষ্ট ফাংশন ব্যবহার: JPQL অনেক সময় ডেটাবেস নির্দিষ্ট ফাংশন বা বৈশিষ্ট্য সমর্থন করে না। Native Query ব্যবহার করে সরাসরি SQL কুয়েরি ব্যবহার করা যায় যা ডেটাবেসের সকল ক্ষমতা কাজে লাগাতে সহায়তা করে।
- কাস্টম এবং জটিল কুয়েরি: JPQL-এ জটিল কুয়েরি লেখার ক্ষেত্রে কিছু সীমাবদ্ধতা থাকতে পারে। Native Query ব্যবহার করে আপনি যেকোনো জটিল SQL কুয়েরি তৈরি করতে পারবেন।
- পারফরম্যান্স: কিছু ক্ষেত্রে, Native Query এর মাধ্যমে কুয়েরি অপটিমাইজ করা সম্ভব হয়, যা পারফরম্যান্স বৃদ্ধি করতে সহায়তা করে।
- Stored Procedures এবং Functions: ডেটাবেসের স্টোরড প্রসিডিউর বা ফাংশন কল করার জন্য Native Query ব্যবহৃত হয়।
Native Query ব্যবহার কিভাবে করবেন
Spring Data JPA-তে Native Query ব্যবহার করতে @Query অ্যানোটেশন এবং nativeQuery = true প্যারামিটার ব্যবহার করা হয়। যখন আপনি nativeQuery = true সেট করেন, তখন Spring Data JPA SQL কুয়েরি হিসেবে সেটি এক্সিকিউট করবে।
উদাহরণ: Native Query ব্যবহার
ধরা যাক, একটি Employee Entity আছে এবং আপনি Employee টেবিল থেকে নির্দিষ্ট শর্ত অনুযায়ী ডেটা খুঁজে বের করতে চান। নিচে একটি উদাহরণ দেখানো হলো:
@Entity
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String position;
private double salary;
// Getters and Setters
}
Repository Interface-এ Native Query ব্যবহার:
public interface EmployeeRepository extends JpaRepository<Employee, Long> {
// Native Query with nativeQuery = true
@Query(value = "SELECT * FROM Employee e WHERE e.position = :position", nativeQuery = true)
List<Employee> findByPosition(String position);
// Native Query with Named Parameters
@Query(value = "SELECT * FROM Employee e WHERE e.salary > :salary", nativeQuery = true)
List<Employee> findBySalaryGreaterThan(@Param("salary") double salary);
// Using Aggregation function with Native Query
@Query(value = "SELECT AVG(e.salary) FROM Employee e", nativeQuery = true)
double findAverageSalary();
}
এখানে:
- findByPosition: একটি Native SQL কুয়েরি যা
Employeeটেবিল থেকে নির্দিষ্টpositionঅনুসারেEmployeeরেকর্ড খুঁজে বের করবে। - findBySalaryGreaterThan: Native SQL কুয়েরি যা
salaryথেকে বড়Employeeরেকর্ডগুলো বের করবে। - findAverageSalary: একটি Native SQL কুয়েরি যা
Employeeটেবিলেরsalaryএর গড় বের করবে।
Service Layer:
@Service
public class EmployeeService {
@Autowired
private EmployeeRepository employeeRepository;
public List<Employee> getEmployeesByPosition(String position) {
return employeeRepository.findByPosition(position);
}
public List<Employee> getEmployeesBySalary(double salary) {
return employeeRepository.findBySalaryGreaterThan(salary);
}
public double getAverageSalary() {
return employeeRepository.findAverageSalary();
}
}
Controller Layer:
@RestController
@RequestMapping("/employees")
public class EmployeeController {
@Autowired
private EmployeeService employeeService;
@GetMapping("/position/{position}")
public List<Employee> getEmployeesByPosition(@PathVariable String position) {
return employeeService.getEmployeesByPosition(position);
}
@GetMapping("/salary/{salary}")
public List<Employee> getEmployeesBySalary(@PathVariable double salary) {
return employeeService.getEmployeesBySalary(salary);
}
@GetMapping("/average-salary")
public double getAverageSalary() {
return employeeService.getAverageSalary();
}
}
Native Query এর ব্যবহারযোগ্য ক্ষেত্র
- SQL ফিচারের ব্যবহার: যদি ডেটাবেসের স্পেসিফিক ফিচার বা ফাংশন (যেমন,
GROUP BY,HAVING, বা ডেটাবেসের নিজস্ব ফাংশন) ব্যবহার করতে হয়, তখন Native Query ব্যবহৃত হয়। - Stored Procedures: যদি আপনি ডেটাবেসের স্টোরড প্রসিডিউর বা ফাংশন কল করতে চান, তবে Native Query প্রয়োজনীয়।
- Complex SQL Queries: খুব জটিল SQL কুয়েরি, যেমন টেবিলের মধ্যে জটিল
JOINবাUNIONঅপারেশন, যে ধরনের জটিল কুয়েরি JPQL দিয়ে করা সম্ভব নয়। - Performance Optimization: যখন কিছু অপটিমাইজড কুয়েরি বা ইনডেক্স ব্যবহারের প্রয়োজন হয় এবং JPQL তা সাপোর্ট না করে, তখন Native Query ব্যবহার করা হয়।
সারাংশ
Native Query হল Spring Data JPA-তে ডেটাবেস স্পেসিফিক কুয়েরি লিখে ডেটা অ্যাক্সেস করার একটি পদ্ধতি। এটি ডেটাবেসের শক্তিশালী এবং স্পেসিফিক ফিচার ব্যবহার করতে সাহায্য করে, যেমন স্টোরড প্রসিডিউর, কাস্টম SQL ফাংশন বা ডেটাবেস স্পেসিফিক অপারেশন। JPQL এবং HQL এর সীমাবদ্ধতা কাটিয়ে Native Query ডেটাবেসের অগ্রিম ফিচার ব্যবহার করে পারফরম্যান্স বৃদ্ধি করতে সহায়তা করে। তবে, Native Query ব্যবহারের সময় ডেটাবেসের স্পেসিফিক ফিচার সমর্থন করা উচিত এবং ডেটাবেস নির্দিষ্ট কুয়েরি ব্যবহার করলে পোর্টেবিলিটি সমস্যা হতে পারে।